package com.lifl.b328.garden.model;

import java.util.Date;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.database.Cursor;


public class Cache extends Storage {
	protected CacheDAO<Note> noteDAO;
	protected CacheDAO<User> userDAO;
	protected CacheDAO<UserNote> user_noteDAO;
	protected CacheDAO<CoupleLocalDistant> userLocDistDAO;
	protected CacheDAO<CoupleLocalDistant> noteLocDistDAO;
		
	protected DatabaseHelper database;
	
	public Cache(Context context){
		database = new DatabaseHelper(context);
		noteDAO = new NoteCacheDAO();
		userDAO = new UserCacheDAO();
		user_noteDAO = new UserNoteCacheDAO();
		userLocDistDAO = new UserLocDistDAO();
		noteLocDistDAO = new NoteLocDistDAO();
		
	}
	@Override
	public void addNote(Note n,long userId,long noteId, Handler handler) {
		//insertion dans la table note
		noteDAO.setDB(database.getWritableDatabase());
		MonLog.print("ajout de la note dans la table note",this.getClass());
		long rownote = noteDAO.add(n);
		MonLog.print("ajout note reussi",this.getClass());
		MonLog.print("ajout dans la table noteuser le couple note user",this.getClass());
		//insertion dans la table usernote 
		user_noteDAO.setDB(database.getWritableDatabase());
		long rowun = user_noteDAO.add(new UserNote(rownote, userId));
		
		MonLog.print("ajout user note reussi",this.getClass());
		//fermeture de la base
		database.close();
		//traitement fini on appelle la reponse
		if(rowun > 0)
			handler.onResponse();
		else
			handler.onError();
		//envoi au storage suivant
		super.addNote(n, userId, rownote,null);
	}

	@Override
	public void deleteNote(long id,User user, final Handler handler) {
		MonLog.print("efface note id : "+id, this.getClass());
		MonLog.print("Cache delete", getClass());
		noteDAO.setDB(database.getWritableDatabase());
		long res = noteDAO.delete(id);
		database.close();
		if(res > 0){
			user_noteDAO.setDB(database.getWritableDatabase());
			user_noteDAO.delete(id);
			database.close();
		}
		//envoi au storage suivant
		super.deleteNote(id,user ,new Handler() {
			
			@Override
			public void onResponse(Object... objet) {
				handler.onResponse();
			}
			
			@Override
			public void onRelease() {
			}
			
			@Override
			public void onProgress() {
			}
			
			@Override
			public void onError() {
				handler.onError();
			}
		});
		
	}
	
	@Override
	public long editNote(Note note,long id){
		MonLog.print("edition note : "+id, this.getClass());
		noteDAO.setDB(database.getWritableDatabase());
		long res = noteDAO.edit(note, id);
		database.close();
		//storage suivant;
		//super.editNote(note, id);
		return res;
		//return (res > 0)?super.editNote(note,id): id;
	}
	
	private void mettreAJourNote(Note note, long id,long userid){
		noteLocDistDAO.setDB(database.getWritableDatabase());
		CoupleLocalDistant cld = noteLocDistDAO.getById(id);
		MonLog.print("local : "+cld.local+" distant :"+cld.distant,getClass());
		long idLocal = cld.getLocal();
		if(idLocal > 0){
			noteDAO.setDB(database.getWritableDatabase());
			noteDAO.edit(note, idLocal);
			System.out.println("edit note "+idLocal);
		}
		else
		{
			noteDAO.setDB(database.getWritableDatabase());
			long rownote = noteDAO.add(note);
			System.out.println("nouvelle note ");
			System.out.println(rownote);
			noteLocDistDAO.add(new CoupleLocalDistant(rownote, id));
			user_noteDAO.setDB(database.getWritableDatabase());
			user_noteDAO.add(new UserNote(rownote,userid));
		}
		database.close();
	}
	
	@Override
	public void getAllNotes(User user,long user_id,Handler handler) {
		getAllNotes(user,user_id, null, handler);
	}
	
	@Override
	public void getAllNotes(final User user,final long user_id, String order,final Handler handler){
		MonLog.print("getAllNote in json via notepool", getClass());
		super.next.getAllNotes(user,user_id,new Handler() {
			
			@Override
			public void onResponse(Object... objet) {
				MonLog.print("onResponse", Cache.class);
				try{
					JSONArray json = (JSONArray) objet[0];
					int l = json.length();
					Note note;
					for(int i = 0; i < l; i++)
					{
							MonLog.print(json.get(i)+"", getClass());
							note = JSONToNote(json.getJSONObject(i));
							note.user = user;
							mettreAJourNote(note, json.getJSONObject(i).getLong("id"),user.id);
					}
					onError();
				}catch (Exception e) {
						e.printStackTrace();
				}
			}
			
			@Override
			public void onRelease() {
			}
			
			@Override
			public void onProgress() {
				handler.onProgress();
			}
			
			@Override
			public void onError() {
				MonLog.print("on error=>"+user_id, getClass());
				noteDAO.setDB(database.getReadableDatabase());
				Cursor cursor = noteDAO.getAll(user_id);
				database.close();
				handler.onResponse(cursor);
			}
		});
		
		//super.getAllNotes(idUser);
	}
	
	@Override
	public Note getNoteById(long id){
		noteDAO.setDB(database.getReadableDatabase());
		Note note= noteDAO.getById(id);
		database.close();
		//super.getNoteById(id);
		return note;
	}
	
	public User getUserByEmail(String email){
		
		userDAO.setDB(database.getWritableDatabase());
		User user = userDAO.getByColumn(Constantes.KEY_USER_EMAIL,email);
		database.close();
		
		return user;
	}
	
	public void addUser(final User user, final Handler handler){
		userDAO.setDB(database.getWritableDatabase());
		long rowid = userDAO.add(user);
		database.close();
		userLocDistDAO.setDB(database.getWritableDatabase());
		final long id = userLocDistDAO.add(new CoupleLocalDistant(rowid, -1));
		user.setID(id);
		user.setToken("monToken");
		database.close();
		
		super.next.addUser(user, new Handler() {
			@Override
			public void onResponse(Object... objet) {
				handler.onResponse(id);
			}
			@Override
			public void onRelease() {
			}
			@Override
			public void onProgress() {
			}
			@Override
			public void onError() {
				MonLog.print("onError", getClass());
				handler.onResponse(id);				
			}
		});
		
	}

	private Note JSONToNote(JSONObject json) throws JSONException{
		Note n = new Note();
		String desc = json.getString(Constantes.KEY_VIEW_NOTEUSER_CONTENT);
		String url = json.getString(Constantes.KEY_VIEW_NOTEUSER_PHOTOURL);
		Date create = Tools.stringToDate(json.getString(Constantes.KEY_VIEW_NOTEUSER_CREATION));
		Date edition = Tools.stringToDate(json.getString(Constantes.KEY_VIEW_NOTEUSER_EDITION));
		double longitude = json.getLong(Constantes.KEY_VIEW_NOTEUSER_LONGITUDE);
		double latitude = json.getLong(Constantes.KEY_VIEW_NOTEUSER_LATITUDE);
		n.addContent(Constantes.NOTE_CONTENT, new TextContent(desc));
		n.addContent(Constantes.NOTE_CREATION, new DateContent(create));
		n.addContent(Constantes.NOTE_EDITION, new DateContent(edition));
		n.addContent(Constantes.NOTE_GPS, new CoordonneesContent(latitude, longitude));
		n.addContent(Constantes.NOTE_PHOTO, new PhotoContent(url));
		
		return n;		
	}
		
}
